﻿using System;
using System.ComponentModel;
using System.Windows.Forms;
using System.Xml;
using CppProject;

namespace BackEndProcessorInterface
{
    internal class EventModel
    {
        private static TopForm _mainForm;
        protected static CppController _cppController;
        private static readonly AboutBox about = new AboutBox();
        private readonly BackgroundWorker backWorker = new BackgroundWorker();
        private static PostProcessorFiles ppf;
        private static readonly PConfig filters = new PConfig();

        public EventModel(TopForm mainForm, CppController cppController)
        {
            _mainForm = mainForm;
            _cppController = cppController;

            filters.Add("default","All files(*.*)|*.*");
            filters.Add("txt","(TXT)|*.txt");
            filters.Add("xls", "(XLS;XLSX)|*.xls;*.xlsx");
            filters.Add("xml", "(XML)|*.xml");
            filters.Add("proc","(ppc)|*.ppc");

            filters.Separation = "|";

            backWorker.DoWork += backWorker_DoWork;
            backWorker.RunWorkerCompleted += backWorker_RunWorkerCompleted;
        }
        private static void backWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            _mainForm.SetText(SDate, "Completed:: " + e.Result);
            _mainForm.SetTask("Saving Completed");
        }
        private static void backWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            var saver = (BackWorkFiles) e.Argument;
            saver._SaveFlag();

           // Thread.Sleep(10000); // test

            e.Result = "SaveFlag:: " + saver.FILE_NAME;
        }

        public void CheckGraphicsSettings(object obj, EventArgs ea)
        {
            if (obj is MenuItem)
            {
                var mi = (MenuItem) obj;
                mi.Checked = !mi.Checked;
                _mainForm.SetGraphicsSetting(mi.Name, mi.Checked);
              
            }

        }
       public void ScaleMinMaxValue(object obj, EventArgs ea)
       {
           if (!(obj is MenuItem)) return;
           var mi = (MenuItem)obj;
           var name = mi.Name;
           _mainForm.ScaleGrad(name);
         
       }
        public void NewFileClick(object obj, EventArgs ea)
        {
            if (obj is MenuItem)
                Plug(((MenuItem) obj).Text);
        }

        public void OpenFileClick(object obj, EventArgs ea)
        {
            var name = ((MenuItem) obj).Name;
            string filename = name == "proc" ? ChooserFileDialog(false, (string)filters[name], "Открыть proc-format") :
                ChooserFileDialog(false, filters.ValueToString(), "Открыть " + ((MenuItem)obj).Text);

                if (filename != null)
                {
                    switch (name)
                    {
                        case "settings":
                            if (!LoadInterfaceSettings(filename))
                                MessageBox.Show("Can't load interface settings", "Loading error", MessageBoxButtons.OK,
                                                MessageBoxIcon.Error);
                            break;
                        case "task":
                            try
                            {
                                var d = new XmlDocument();
                                d.Load(filename);

                                string dir = System.IO.Path.GetDirectoryName(filename) + "\\";


                                string inf2trfile = dir + d.GetElementsByTagName("inf2trfile").Item(0).InnerText;
                                string globalnumberfile = dir +
                                                          d.GetElementsByTagName("globalnumberfile").Item(0).InnerText;
                                string solutionfile = dir + d.GetElementsByTagName("solutionfile").Item(0).InnerText;
                                string vertexfile = dir + d.GetElementsByTagName("vertexfile").Item(0).InnerText;
                                string materialsfile = dir + d.GetElementsByTagName("materialsfile").Item(0).InnerText;

                                _cppController.OpenTask(inf2trfile, globalnumberfile, vertexfile, solutionfile,
                                                        materialsfile);
                            }
                            catch (Exception ex)
                            {
                                MessageBox.Show(ex.Message, "Loading error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                            }


                            break;
                        case "proc":
                            try
                            {
                                string isoline = "";
                                string colorscale = "";
                                _cppController.LoadFromPostProcFile(filename, ref colorscale, ref isoline);
                                _mainForm.ColorScaleFromString(colorscale);
                                _mainForm.IsoLinesFromString(isoline);
                            }
                            catch (Exception ex)
                            {
                                MessageBox.Show(ex.Message, "Loading error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                            }

                            break;
                    }
                }
                else return;


            }
        public void SaveAllFileClick(object obj, EventArgs ea)
        {
            var filter = string.Format("{0}|{1}", filters["xml"], filters["default"]);
            string filename = ChooserFileDialog(true, filter, "Cохранить натсройки");
            if (filename != null)
                if (ppf == null)
                    ppf = new PostProcessorFiles {Name = "Interface", FileName = filename};
                else
                    ppf.Clear();
            else
                return;

            ppf.FileName = filename;
            ppf.Add(_mainForm.GetGraphicsConfig);
            ppf.Add(_mainForm.GetPanelConfig);
#if(DEBUG)
            _mainForm.SetText(SDate, string.Format("Сохранение прошло : {0}", ppf.Save(ppf.FileName)));
#else         
                     ppf.Save(ppf.FileName);
#endif
            FormatSave("proc","Сохранить настройки цвета и изолиний ");                 //Сохраняем градиент и изолинии
            FormatSave("txt","Сохранить флаги в текстовом формате" );                  //Сохраняем флаги

        }
        public void SaveFileClick(object obj, EventArgs ea)
        {
            if (ppf == null)
            {
                string filename = ChooserFileDialog(true, filters.ValueToString(),"Сохранить настройки");
                if (filename != null)
                {
                    ppf = new PostProcessorFiles(filename) {Name = "Interface"};
                }
                else return;
            }
            ppf.Add(_mainForm.GetGraphicsConfig);
            ppf.Add(_mainForm.GetPanelConfig);

#if(DEBUG)

            _mainForm.SetText(SDate, string.Format("Сохранение прошло : {0}", ppf.Save(ppf.FileName)));
#else
                ppf.Save(ppf.FileName);
#endif
        }

        //TODO: When isoline will be complite
            /*
        public void SettingIsolineClick(object obj, EventArgs ea)
        {
            if (obj is MenuItem)
                Plug(((MenuItem)obj).Text);
        }
         * */
        public void ChooserMousePointer
            (object obj, EventArgs ea)
        {
            var mi = (MenuItem) obj;
            var iter = mi.Parent.MenuItems.GetEnumerator();
            while (iter.MoveNext())
            {
                var data = (MenuItem) iter.Current;
                if (data.Index != mi.Index)
                    data.Checked = mi.Checked;
            }
            mi.Checked = !mi.Checked;
            _mainForm.MousePointerButton(mi.Name, mi.Checked);

            switch (mi.Name)
            {
                case "toolStripButtonFlag":
                    mi.MenuItems.Add(new MenuItem("Добавить", AddFlag));
                    mi.MenuItems.Add(new MenuItem("Удалить", RemoveAllFlag));
                    break;
                case "toolStripButtonMouseDefault":
                    mi.Parent.MenuItems["toolStripButtonFlag"].MenuItems.Clear();
                    break;
            }
           
        }

        public void AddFlag(object obj, EventArgs ea)
        {
            var mi = (MenuItem)obj;
                mi.Checked = true;
                mi.Enabled = false;
            _mainForm.AddFlag();
            
        }
        public void RemoveAllFlag(object obj, EventArgs ea)
        {
            _mainForm.RemoveFlags();
        }

        public void SettingSaveClick(object obj, EventArgs ea)
            {
                if (obj is MenuItem)
                    Plug(((MenuItem) obj).Text);
            }
        public void HelpShowClick(object obj, EventArgs ea)
            {
                if (obj is MenuItem)
                    Plug(((MenuItem) obj).Text);
            }
        public void AboutClick(object obj, EventArgs ea)
            {
                if (about != null) about.ShowDialog(_mainForm);
            }

        public void PrintFileClick(object obj, EventArgs ea)
        {
            if (obj is MenuItem)
                Plug(((MenuItem) obj).Text);
        }

        public void ViewClick(object obj, EventArgs ea)
        {
            var mi = (MenuItem) obj;
            mi.Checked = !mi.Checked;
            _mainForm.ViewButton(mi.Name, mi.Checked);
        }
        public void ExitFileClick
            (object obj, EventArgs ea)
            {
                // if (obj is MenuItem)
                //     Plug(((MenuItem)obj).Text);
                _mainForm.Close();
            }

        public void FormatSaveFileClick(object obj, EventArgs ea)
        {
            FormatSave(((MenuItem)obj).Name, "Сохранить" + ((MenuItem)obj).Text);
        }

        public void DataFormatSaveFileClick(object obj, EventArgs ea)
            {
                if (obj is MenuItem)
                    Plug(((MenuItem) obj).Text);
            }
        public void CsvFormatSaveFileClick(object obj, EventArgs ea)
            {
                if (obj is MenuItem)
                    Plug(((MenuItem) obj).Text);
            }
        /*
        public void ProcFormatSaveFileClick(object obj, EventArgs ea)
            {
                FileDialog fDialog = new SaveFileDialog();

                fDialog.Filter = "(ppc)|*.ppc|All files(*.*)|*.*";
                if (fDialog.ShowDialog() == DialogResult.OK)
                {
                    _cppController.SaveToPostProcFile(fDialog.FileName, _mainForm.ColorScaleToString(),
                                                      _mainForm.IsoLinesToString());
                }
            }
         * */
        public bool LoadInterfaceSettings(string filename)
        {
            ppf = new PostProcessorFiles {FileName = filename};
            ppf.Load(filename);
            if ("Interface".Equals(ppf.Name))
            {
                var pconfig = ppf.GetConfig("Graphics");
                if (pconfig == null)
                {
                    _mainForm.ShowErrorBox("Config with name: \"Graphics\" not found!");
                }
                else
                {
                    _mainForm.SetGraphicsSetting("checkBoxAxis", pconfig.asBool("BoxAxis", false));
                    _mainForm.SetGraphicsSetting("checkBoxMesh", pconfig.asBool("BoxMesh", false));
                    _mainForm.SetGraphicsSetting("checkBoxMeshFI", pconfig.asBool("BoxMeshFI", false));
                    _mainForm.SetGraphicsSetting("checkBoxIsoline", pconfig.asBool("BoxIsoline", false));
                    _mainForm.SetGraphicsSetting("checkBoxFlags", pconfig.asBool("BoxFlags", false));
                }
                pconfig = ppf.GetConfig("Panels");
                if (pconfig == null)
                {
                    _mainForm.ShowErrorBox("Config with name: \"Panels\" not found!");
                }
                else
                {
                    _mainForm.ViewButton("toolStripButtonPanelLog", pconfig.asBool("Console", false));
                    _mainForm.ViewButton("toolStripButtonPanelRight", pconfig.asBool("ToolPanel", false));
                }
              
                return true;
                
            }
            return false;
        }
        public void Plug(object obj, EventArgs ea)
        {
            if (obj is MenuItem)
                Plug(((MenuItem)obj).Text);
        }
        public void Plug(String message)
        {
            Plug(SDate, message);
        }
        private static void Plug(String date, String message)
        {
            MessageBox.Show(_mainForm, String.Format("[{0}]: <DEBUG> {1}", date, message),
                            "Info", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }

        private static String SDate
        {
            get
            {
                return DateTime.Now.ToString("dd.MM.yyyy HH:mm:ss");
            }
        }
        public String PSDate
        {
            get
            {
                return SDate;
            }
        }
        private static string ChooserFileDialog(bool savefiledialog, string filter,string title)
        {
            FileDialog fDialog;
            if (savefiledialog) fDialog = new SaveFileDialog();
            else fDialog = new OpenFileDialog();
            fDialog.Title = title;
            fDialog.Filter = filter;
            if (fDialog.ShowDialog(_mainForm) == DialogResult.Cancel)
                return null;

            string filename = fDialog.FileName;
            if (string.IsNullOrEmpty(filename))
            {
                MessageBox.Show("Имя файла не известно!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return null;
            }
            return filename;

        }
        private void FormatSave(string name,string title)
        {
            var filter = string.Format("{0}|{1}", filters[name], filters["default"]);
            string filename = ChooserFileDialog(true, filter,title);
            if (filename == null)
                return;

            try
            {
                _mainForm.SetTask("Saving...");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            backWorker.RunWorkerAsync(new BackWorkFiles(name, filename));
        }

        class BackWorkFiles
        {
            public
                BackWorkFiles(string
                name,
                string filename)
            {
                if (name != null) NAME = name;
                if (filename != null) FILE_NAME = filename;
            }

            public void _SaveFlag()
            {
                if (_cppController == null)
                    return;
                try
                {
                    switch (NAME)
                    {
                        case "txt":
                            _cppController.ExportToTxt(FILE_NAME);
                            break;
                        case "xls":
                            _cppController.ExportToXls(FILE_NAME);
                            break;
                        case "proc":
                            _cppController.SaveToPostProcFile(FILE_NAME, _mainForm.ColorScaleToString(),
                                                      _mainForm.IsoLinesToString());
                            break;
                            

                    }

                }
                catch (Exception e)
                {
                    MessageBox.Show(e.Message);
                }
            }

            public readonly string FILE_NAME;
            public readonly string NAME;


        }

        }
    } 
